import { Card, Layout } from 'antd';
import classNames from 'classnames';
import { cloneDeep } from 'lodash-es';
import React from 'react';
import {
  generateLayerId,
  OperationType
} from '@/pages/TemplateEditor/constant';
import { LayerInfoFE, ScreenRefType } from '@/pages/TemplateEditor/interface';

import { LayerTypeBE } from '../../constant';
import { emitter, EVENT_TYPE } from '../../events';
import { generateCopyLayerName, getInitialLayerData } from '../../utils';
import Buttons from './components/Buttons';
import LayerList from './components/LayerList';
import styles from './index.module.less';
import {
  hasOtherLayers,
  isDisableNewLayer,
  isDisableProductLayer,
  isTextLayer
} from './utils';

const { Sider } = Layout;

interface Props {
  screenRef: ScreenRefType;
  activeKey: string;
  layers: LayerInfoFE[];
  screenSize: string;
  operationType: OperationType;
  onUpdate: (
    layers: LayerInfoFE[],
    needRealTimePreview?: boolean,
    activeKey?: string,
    needRerender?: boolean
  ) => void;
  onSetActive: (key: string) => void;
  onSetCropLayerId: (id: string) => void;
  setScreenSize: (size: string) => void;
}

const Layers = ({
  screenRef,
  activeKey,
  layers,
  screenSize,
  operationType,
  onUpdate,
  onSetActive,
  setScreenSize,
  onSetCropLayerId
}: Props): JSX.Element => {
  const disableNewLayer = isDisableNewLayer(layers);
  const disableProductLayer = isDisableProductLayer(layers);

  const handleAddLayer = (type: LayerTypeBE): void => {
    const newLayer = getInitialLayerData(type, layers, screenSize);
    const newList = [...layers, newLayer];
    // 此处第二个参数需要增加判断，是否需要realtime preview，文字修改样式时需要设置为true，只修改位置、角度时不必调用
    onUpdate(newList, isTextLayer(newLayer), newLayer.data.id);
  };

  const handleChangeLayer = (
    index: number,
    layer: LayerInfoFE,
    needUpdateForm = false,
    needRerenderScreen = false
  ): void => {
    const newList = [...layers];
    newList[index] = layer;

    if (needUpdateForm) {
      emitter.emit(EVENT_TYPE.resetLayerForm, newList);
    }

    // Shape的type修改，需要进行整个重新渲染
    if (needRerenderScreen) {
      onUpdate(newList, layer.data.needPreview);
      return;
    }

    // 其余单个layer的普通修改，则仅需要渲染单个layer即可，不在update里触发整个重新渲染
    onUpdate(newList, layer.data.needPreview, null, false);
    screenRef.current.rerenderLayer(layer);
  };

  const handleCopyLayer = (index: number): void => {
    const newLayerData = cloneDeep(layers[index]);
    const newList = [
      ...layers,
      {
        ...newLayerData,
        data: {
          ...newLayerData.data,
          id: generateLayerId(newLayerData.data.type),
          name: generateCopyLayerName(
            newLayerData.data.name,
            layers.map((item) => item.data.name)
          ),
          needPreview: isTextLayer(newLayerData)
        }
      }
    ];
    onUpdate(newList, isTextLayer(newLayerData));
  };

  const handleRemoveLayer = (index: number): void => {
    const newList = [...layers];
    newList.splice(index, 1);
    onUpdate(newList);
  };

  return (
    <Sider
      className={classNames('bg-white h-full pb-4', styles.container)}
      width={394}
    >
      <Card
        className={classNames(
          'border-none',
          'shrink-0',
          styles['button-container']
        )}
      >
        <div className="text-base leading-4 mb-4">Layers</div>

        <Buttons
          operationType={operationType}
          disableNewLayer={disableNewLayer}
          disableProductLayer={disableProductLayer}
          onAddLayer={handleAddLayer}
        />
      </Card>

      <div className="flex-grow overflow-y-auto">
        <LayerList
          activeKey={activeKey}
          layers={layers}
          screenSize={screenSize}
          disableNewLayer={disableNewLayer}
          disableProductLayer={disableProductLayer}
          onChange={handleChangeLayer}
          onCopy={handleCopyLayer}
          onRemove={handleRemoveLayer}
          onSetActive={onSetActive}
          onUpdate={onUpdate}
          setScreenSize={setScreenSize}
          onSetCropLayerId={onSetCropLayerId}
        />
      </div>
    </Sider>
  );
};

export default Layers;
